# BingSearch class which is able to use Bing Search results as a list
# @note The class BingSearch will use an AppId of bing Developer Center which is registered to Richard Cornelissen, please use your own!
# @author Richard Cornelissen

from pybing.query import WebQuery
from HIT.metasearch import SearchEngine
import math

class BingSearch(SearchEngine):
    
    APPID = u'ID_COMES_HERE' #TODO: Add App ID, see http://www.bing.com/developers and then "Create an AppID"
    NAME = u'Bing'
    LOGO = u'bing.png'
    MAX_RESULTS = 1000
    
    def __init__(self, query, cache_before = 20):
        self.query = unicode(query)
        cache_before = math.ceil(cache_before / 10.0) * 10 #Make sure a multiple of 10 is cached before using this set
        
        self.wquery = WebQuery(BingSearch.APPID, query = self.query)
        self._bing_results = self.wquery.execute()
        self._results = []
        self._get_results(cache_before)
    
    # __getitem__ function, enables the use of BingSearch[x]
    def __getitem__(self, key):
        if isinstance(key, int):
            if key > self.MAX_RESULTS:
                return None
            
            if key >= len(self._results):
                self._get_results(key)
            
            return self._results(key)
        
        elif isinstance(key, slice):
            if key.start > self.MAX_RESULTS:
                return [None]
            
            if key.stop > self.MAX_RESULTS:
                key.stop = self.MAX_RESULTS
            
            if key.stop > len(self._results):
                self._get_results(key.stop)
            
            return self._results[key]
    
    def __len__(self):
        return len(self._results)
    
    # Function that gets results, using pybing
    def _get_results(self, max):
        max = int(math.ceil(max / 10.0) * 10)
        res = self._bing_results[len(self._results) : max]
        converted_res = self._convert_results(res)
        self._results = self._results + converted_res
    
    # Function that converts a result from pybing into a dictionary
    def _convert_results(self, results):
        res = []
        for r in results:
            if not r.url: continue
            
            newr = {'url': r.url, 'desc': '', 'title': ''}
            if not r.title:
                newr['title'] = r.url
            else:
                newr['title'] = r.title
            
            if not r.description:
                newr['desc'] = ''
            else:
                newr['desc'] = r.description
            
            res.append(newr)
        return res